﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Business;
using Business.Entity.Estoque.Produto;
using Business.Entity.Vendas.Pedido;
using Business.Entity.Vendas.Pedido.ClassesRelacionadas;
using Business.Entity.Vendas.Pedido.Mercearia;
using Business.Entity.Vendas.Pedido.Restaurante;
using Business.Enum;
using Ecf;
using Ecf.Enum;
using Ecf.Forms;
using FluentNHibernate.Conventions;
using Vendas.Forms;

namespace Vendas
{
    public class VendaUtils
    {
        private static string TributosIbpt { get; set; }
        public static bool FecharPedidoMercearia(Mercearia pedido)
        {
            if (pedido.Produtos.Count == 0)
            {
                throw new Exception("Informe ao menos um produto para poder fechar o pedido.");
            }
            var s = MerceariaRepository.GetSession();
            CondicaoPagamentoRepository.Session = s;
            FormaPagamentoRepository.Session = s;
            var formas = FormaPagamentoRepository.GetList().Where(forma => forma.PodeReceber).ToList();
            var condicoes = CondicaoPagamentoRepository.GetList();
            var pag = new FormPagamentoPedido(CalcularValorPedidoMercearia(pedido), formas,
                condicoes);
            pag.ShowDialog();
            if (pag.DialogResult == DialogResult.Cancel)
            {
                return false;
            }
            pedido.Pagamento = pag.GetPagamentoPedido();
            pedido.CondicaoPagamento = pag.GetCondicaoPagamento();
            pedido.Acressimos = pag.GetAcressimos();
            pedido.Descontos = pag.GetDesconto();
            pedido.Frete = pag.GetFrete();
            pedido.ValorPedido = pag.Total;

            // quando do uso de cupom fiscal deve ser chamado o comando de impressão aqui.
            MerceariaRepository.Save(pedido);
            return true;
        }

        private static decimal CalcularValorPedidoMercearia(Mercearia mercearia)
        {
            decimal total = 0;
            foreach (var prod in mercearia.Produtos)
            {
                total += prod.Valor;
            }
            return total;
        }

        public static bool FecharPedidoRestaurante(PedidoRestaurante pedido)
        {
            try
            {
                if (pedido.Produtos.Count == 0)
                {
                    throw new Exception("Informe ao menos um produto para poder fechar o pedido.");
                }

                var s = PedidoRestauranteRepository.GetSession();

                CondicaoPagamentoRepository.Session = s;
                FormaPagamentoRepository.Session = s;
                var formas = FormaPagamentoRepository.GetList().Where(forma => forma.PodeReceber).ToList();
                var condicoes = CondicaoPagamentoRepository.GetList();
                var pag = new FormPagamentoPedido(PedidoRestauranteRepository.CalcularValorPedidoRestaurante(pedido),
                    formas, condicoes);
                pag.ShowDialog();
                if (pag.DialogResult == DialogResult.Cancel)
                {
                    return false;
                }
                pedido.Pagamento = pag.GetPagamentoPedido();
                pedido.CondicaoPagamento = pag.GetCondicaoPagamento();
                pedido.Acressimos = pag.GetAcressimos();
                pedido.Descontos = pag.GetDesconto();
                pedido.Frete = pag.GetFrete();
                pedido.ValorPedido = pag.Total;


                if (!FecharPedidoRestaurante(pedido, GetProdutosDeComposicao(pedido), pedido.Pagamento)) return false;
                pedido.Coo = EcfHelper.GetEcf().UltimoCupomEmitido();
                PedidoRestauranteRepository.Save(pedido);

            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro ao gravar pedido.\n" + ex.Message + "\n" +
                                "Mensagem do erro: " + ex.InnerException);
                return false;

            }
            return true;
        }

        public static IList<ProdutoPedido> GetProdutosDeComposicao(PedidoRestaurante pedido)
        {
            var prods = new List<ProdutoPedido>();
            foreach (var composicao in pedido.Produtos)
            {
                foreach (var prod in composicao.Composicao)
                {
                    prod.Valor /= composicao.Composicao.Count;
                    prods.Add(prod);
                }
            }
            return prods;
        }

        private static bool FecharPedidoRestaurante(Pedido pedido, IList<ProdutoPedido> produtos,
            IList<PagamentoPedido> pagamento)
        {
            var clienteCupom = new ClienteCupom();
            if (pedido.Cliente != null)
            {
                if (pedido.Cliente.Id != Utils.Configuracao.PessoaPadrao.Id)
                {
                    clienteCupom.CpfCnpj = pedido.Cliente.CpfCnpj;
                    clienteCupom.Nome = pedido.Cliente.Nome;
                    if (pedido.Cliente.Enderecos != null && !pedido.Cliente.Enderecos.IsEmpty())
                    {
                        clienteCupom.Endereco = pedido.Cliente.Enderecos[0].Logradouro;
                    }
                }
            }
            var solicitaDadoCliente = new FormSolicitaDadosCliente(clienteCupom);
            solicitaDadoCliente.ShowDialog();
            if (!EcfHelper.GetEcf().AbrirCupom(clienteCupom)) return false;
            if (!LancarProdutos(produtos)) return false;
            EcfHelper.GetEcf().IniciaFechamentoCupom(
                TipoDescontoAcressimo.AcressimoValor,
                pedido.Descontos,
                pedido.Acressimos);
            foreach (var pag in pagamento)
            {
                if (!EcfHelper.GetEcf().
                    EfetuarPagamento(pag.FormaPagamento.Descricao, pag.Valor)) return false;
            }

            CalcularTributosDeOlhoNoImposto(produtos);
            if (string.IsNullOrEmpty(pedido.Observacoes))
            {
                if (!EcfHelper.GetEcf().EncerrarCupom(TributosIbpt + Environment.NewLine +
                "Usuário:" + Utils.UsuarioAtual.Pessoa.Nome))
                    return false;
            }
            else
            {
                if (!EcfHelper.GetEcf().EncerrarCupom(TributosIbpt + Environment.NewLine +
                "Usuário:" + Utils.UsuarioAtual.Pessoa.Nome + Environment.NewLine + Environment.NewLine +
                pedido.Observacoes))
                    return false;
            }
            return true;
        }

        public static string CalcularTributosDeOlhoNoImposto(IList<ProdutoPedido> produtos)
        {
            decimal totalProd = 0;
            decimal aliquotaMedia = 0;
            foreach (var prod in produtos)
            {
                totalProd += prod.Valor;
                if (prod.Produto.Origem == OrigemProduto.Nacional)
                {
                    aliquotaMedia += prod.Produto.NCM.TributosNacionalIbpt;
                }
                else
                {
                    aliquotaMedia += prod.Produto.NCM.TributosImportadoIbpt;
                }

            }
            aliquotaMedia = aliquotaMedia / produtos.Count;
            TributosIbpt = "Val Aprox Tributos " +
                    String.Format("{0:c}", (totalProd / 100) * aliquotaMedia) +
                    "(" + EcfHelper.GetEcf().FormataPercentual(aliquotaMedia) + "%) Fonte: IBPT";
            return TributosIbpt;
        }

        private static bool LancarProdutos(IList<ProdutoPedido> produtos)
        {
            foreach (var prod in produtos)
            {

                bool ret;
                if (prod.Produto.Tipo == TipoProduto.Produto || prod.Produto.Tipo == TipoProduto.Mercadoria)
                {

                    ret = EcfHelper.GetEcf().VenderItem(prod.Produto.NCM.Tributacao.TipoTributacaoIcms,
                    prod.Produto.Tipo,
                    prod.Quantidade,
                    prod.ValorUnitario,
                    TipoDescontoAcressimo.AcressimoValor,
                    0,
                    prod.Produto.Id,
                    prod.Produto.UnidadeVenda.Sigla,
                    prod.Produto.Descricao,
                    prod.Produto.NCM.Tributacao.IcmsDevedor);
                }
                else
                {

                    ret = EcfHelper.GetEcf().VenderItem(
                    prod.Produto.NCM.Tributacao.TipoTributacaoIss,
                    prod.Produto.Tipo,
                    prod.Quantidade,
                    prod.ValorUnitario,
                    TipoDescontoAcressimo.AcressimoValor,
                    0,
                    prod.Produto.Id,
                    prod.Produto.UnidadeVenda.Sigla,
                    prod.Produto.Descricao,
                    prod.Produto.NCM.Tributacao.IssDevedor);
                }
                if (!ret)
                {
                    return false;
                }
            }
            return true;
        }
    }
}
